package com.matrix.draft.sockettest.newprotocoltcp;

import com.matrix.draft.sockettest.newprotocoltcp.handler.ClientHandler;
import com.matrix.draft.sockettest.newprotocoltcp.handler.NewProtocolDecoder;
import com.matrix.draft.sockettest.newprotocoltcp.handler.NewProtocolEncoder;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.logging.LoggingHandler;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class NewProtocolTcpClient {

    private String host;
    private Integer port;

    public NewProtocolTcpClient(String host, Integer port) {
        this.host = host;
        this.port = port;
    }

    public void run() {
        EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
        Channel clientChannel;
        try {
            clientChannel = new Bootstrap().group(eventLoopGroup)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<NioSocketChannel>() {
                        @Override
                        protected void initChannel(NioSocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            // Duplex
                            pipeline.addLast(new LoggingHandler());
                            // Out
                            pipeline.addLast(new NewProtocolEncoder());
                            // In
                            pipeline.addLast(new LengthFieldBasedFrameDecoder(2048,18,4,0,0));
                            pipeline.addLast(new NewProtocolDecoder());
                            pipeline.addLast(new ClientHandler());
                        }
                    })
                    .connect(host, port)
                    .addListener(f -> {
                        if (f.isSuccess()) {
                            log.info("The Generic Client has connected to " + host + ":" + port + "...");
                        }
                    })
                    .channel();
            clientChannel.closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            eventLoopGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) {
        new NewProtocolTcpClient("127.0.0.1", 8080).run();
    }
}